import cv2
import matplotlib.pyplot as plt
import numpy as np


def show(img):
    cv2.imshow("img", img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()


img = cv2.imread("./01_Picture/10_contours.png")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
show(thresh)
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)

# 轮廓面积
print(cv2.contourArea(contours[0]))

# 周长 True表示闭合的
print(cv2.arcLength(contours[0], True))

# 传入绘制图像 轮廓 轮廓索引 颜色模式 线条厚度
draw_img = img.copy()
res = cv2.drawContours(draw_img, contours, -1, (0, 0, 255), 2)
show(res)

# 近似原图
img = cv2.imread("./01_Picture/11_contours2.png")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
cnt = contours[0]
draw_img = img.copy()
res = cv2.drawContours(draw_img, [cnt], -1, (0, 0, 255), 2)
show(res)

# 近似 0.1倍周长
epsilon = 0.1 * cv2.arcLength(cnt, True)
approx = cv2.approxPolyDP(cnt, epsilon, True)
draw_img = img.copy()
res = cv2.drawContours(draw_img, [approx], -1, (0, 0, 255), 2)
show(res)

# 边界矩形
img = cv2.imread('01_Picture/10_contours.png')

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)  # 大于17的取255，小于127的取0
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
cnt = contours[0]

x, y, w, h = cv2.boundingRect(cnt)  # 可以得到矩形四个坐标点的相关信息
img = cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255), 2)
show(img)

area = cv2.contourArea(cnt)
rect_area = w * h
extent = float(area) / rect_area
print('轮廓面具与边界矩形比：', extent)

# 外接圆
img = cv2.imread('01_Picture/10_contours.png')

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)  # 大于17的取255，小于127的取0
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
cnt = contours[0]

draw_img = img.copy()
(x, y), redius = cv2.minEnclosingCircle(cnt)
center = (int(x), int(y))
redius = int(redius)
img = cv2.circle(draw_img, center, redius, (0, 255, 0), 2)
show(img)
